struct integral_type{};
struct float_type{};
struct long_type{};
template <typename T>
using what_type=std::conditional_t<std::is_same<T, long>::value || std::is_same<T, long double>::value, long_type, std::conditional_t<std::is_integral<T>::value, integral_type, float_type>>;
template <typename T1, typename T2>
auto mul_impl(T1 v1, T2 v2, long_type){
std::cout<<v1<<"is long type!"<<std::endl;
return v1*v2;
}
template <typename T1, typename T2>
auto mul_impl(T1 v1, T2 v2, integral_type){
std::cout<<v1<<"is integral type!"<<std::endl;
return v1*v2;
}
template <typename T1, typename T2>
auto mul_impl(T1 v1, T2 v2, float_type){
std::cout<<v1<<"is floating point tpye!"<<std::endl;
return v1*v2;
}
template <typename T1, typename T2>
auto mul(T1 v1, T2 v2){
return mul_impl(v1, v2, what_type<T1>());
}